//
// Created by lyx on 2020/3/28.
//

#include <Utils.h>
#include <iostream>
using namespace std;
namespace xio=lyxutils::io;
namespace dbg=lyxutils::debug;
namespace str=lyxutils::str_utils;

struct PointXYZ{
    float x,y,z;
};
struct PointXYZRGB{
    float x,y,z,r,g,b;
};

int main(int argc,char **argv){
    vector<vector<float> > table;
    vector<string> header;
    vector<PointXYZ> pts;
    vector<PointXYZRGB> ptsrgb;
    string path="./";

    cout<<str::center("1.read csv without header",80,'=')<<endl;
    cout<<"read state:"<<endl;
    xio::read_csv(path+"basic_test.txt",table,",",std::cout);
    cout<<"result:"<<endl;
    xio::print2DVector(table,",",false,8,10,10);

    cout<<str::center("2.read exist with header",80,'=')<<endl;
    cout<<"read success?"<<xio::read_csv(path+"basic_header_test.txt",table,header)<<endl;
    cout<<"result:"<<endl;
    xio::printVector(header,",",false,8,10);
    xio::print2DVector(table,",",false,8,10,10);

    cout<<str::center("3.read pts",80,'=')<<endl;
    stringstream ss;
    xio::read_pts(path+"basic_test.txt",pts,",",ss);
    cout<<"read state(from stringstream):"<<endl<<ss.str()<<endl;
    cout<<"result:"<<endl;
    for(auto it=pts.begin();it!=pts.end()&&it!=pts.begin()+10;++it){
        cout<<"x="<<it->x<<",y="<<it->y<<",z="<<it->z<<endl;
    }

    cout<<str::center("4.read pts+fields without header",80,'=')<<endl;
    ofstream ofs("state.txt");
    xio::read_pts_field(path+"basic_test.txt",pts,table,",",ofs);
    cout<<"read state to exist---->state.txt"<<endl;
    cout<<"result:"<<endl;
    for(auto it=pts.begin();it!=pts.end()&&it!=pts.begin()+10;++it){
        cout<<"x="<<it->x<<",y="<<it->y<<",z="<<it->z<<endl;
    }
    cout<<"fields:"<<endl;
    xio::print2DVector(table,",",false,8,10,10);

    cout<<str::center("5.read pts+fields with header",80,'=')<<endl;
    xio::read_pts_field(path+"basic_header_test.txt",pts,header,table,",",cout);
    cout<<"header:";
    xio::printVector(header,",",false,8,10);
    for(auto it=pts.begin();it!=pts.end()&&it!=pts.begin()+10;++it){
        cout<<"x="<<it->x<<",y="<<it->y<<",z="<<it->z<<endl;
    }
    cout<<"fields:"<<endl;
    xio::print2DVector(table,",",false,8,10,10);

    cout<<str::center("6.read ptsrgb",80,'=')<<endl;
    xio::read_ptsrgb(path+"basic_test.txt",ptsrgb,",",cout);
    for(auto it=ptsrgb.begin();it!=ptsrgb.end()&&it!=ptsrgb.begin()+10;++it){
        cout<<"x="<<it->x<<",y="<<it->y<<",z="<<it->z<<",r="<<it->r<<",g="<<it->g<<",b="<<it->b<<endl;
    }

    cout<<str::center("7.read ptsrgb+fields without header",80,'=')<<endl;
    xio::read_ptsrgb_field(path+"basic_test.txt",ptsrgb,table,",",cout);
    for(auto it=ptsrgb.begin();it!=ptsrgb.end()&&it!=ptsrgb.begin()+10;++it){
        cout<<"x="<<it->x<<",y="<<it->y<<",z="<<it->z<<",r="<<it->r<<",g="<<it->g<<",b="<<it->b<<endl;
    }
    cout<<"fields:"<<endl;
    xio::print2DVector(table,",",false,8,10,10);

    cout<<str::center("8.read ptsrgb+fields with header",80,'=')<<endl;
    xio::read_ptsrgb_field(path+"basic_header_test.txt",ptsrgb,header,table,",",cout);
    cout<<"header:";
    xio::printVector(header,",",false,8,10);
    for(auto it=ptsrgb.begin();it!=ptsrgb.end()&&it!=ptsrgb.begin()+10;++it){
        cout<<"x="<<it->x<<",y="<<it->y<<",z="<<it->z<<",r="<<it->r<<",g="<<it->g<<",b="<<it->b<<endl;
    }
    cout<<"fields:"<<endl;
    xio::print2DVector(table,",",false,8,10,10);

    cout<<str::center("9.test files row data miss values",80,'=')<<endl;
    xio::read_csv(path+"miss_value_test.txt",table,",",cout);
    cout<<"result:"<<endl;
    xio::print2DVector(table,",",false,8,10,10);

    cout<<str::center("10.test files with non-numeric values",80,'=')<<endl;
    xio::read_csv(path+"non_numeric_test.txt",table,",",cout);
    cout<<"result:"<<endl;
    xio::print2DVector(table,",",false,8,10,10);
    cout<<str::center("11.test conditional read csv(same data as in test 7)",80,'=')<<endl;
    cout<<"result:"<<endl;
    std::vector<std::vector<float> > table_cond;
    xio::read_csv_if(path+"basic_test.txt",table_cond,[&](const std::vector<float> &row)->bool{return row[5]>100;},",",std::cout);
    xio::print2DVector(table_cond,",",false);
    cout<<"total line of data:"<<table_cond.size()<<endl;
    cout<<str::center("12.test write csv",80,'=')<<endl;
    cout<<"original table size:"<<table_cond.size()<<"x"<<table_cond[0].size()<<endl;
    xio::write_csv("output.txt",table_cond,",",true);
    cout<<str::center("13.test customize read csv",80,'=')<<endl;
    vector<vector<float> > cust_table;
    auto read_row=[&](const vector<float> &row){
        cout<<"reading line:";
        for(auto num:row)cout<<num<<" ";
        cout<<endl;
        cust_table.push_back(row);
    };
    xio::read_csv_customize("basic_test.txt",read_row);
    xio::read_csv_customize("basic_test.txt",read_row,",",cout);
    cout<<"after read twice basic_test.txt to cust_table:"<<endl;
    cout<<"size of cust_table:"<<cust_table.size()<<"x"<<cust_table[0].size()<<endl;
    cout<<"14.add an special case test(small number test)"<<endl;
    vector<vector<float> > scores;
    xio::read_csv("top_match_scores.txt",scores,",");
    xio::print2DVector(scores);
}